<?php
/**
 * @package Waterwheel
 */
/* 
 *  Copyright 2010 Andrew Rickmann
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
require_once(dirname(__FILE__) . '/simpletest/autorun.php');

/**
 *
 * Finds the file the given class name and includes it ready for the class to be instantiated.
 * This is passed to the spl_autoload_register function to automate the process.
 *
 * @param String $classname The name of the class being instantiated.
 */
function application_autoload($classname){
	$path = APPLICATION_PATH . "/../classes" . DIRECTORY_SEPARATOR;
	$file = $path . $classname . '.php';
	if( file_exists($file) ){
		include_once($file);
	}
}

//setup the class autoloader
spl_autoload_register('application_autoload');

define('APPLICATION_PATH' , dirname(__FILE__) );

/**
 * Test of Plugins Class
 *
 * Note, because the app path is this directory this class will use the sample
 * plugins folder included and not the real plugins folder
 *
 * @author Andrew Rickmann
 */
class TestofPlugins extends UnitTestCase {

    /**
     * D before tests
     */
    function setUp() {

    }

    /**
     * Do after tests
     */
    function tearDown() {
        
    }

    /**
     * Tests that an exception gets thrown when a plugin
     * classname is not matched by the filename.
     */
    function testPluginNamingFailure(){

	//first we need to make the badlynamed file into a plugin file
	rename( APPLICATION_PATH . '/plugins/testplugin/badnamed.php', APPLICATION_PATH . '/plugins/testplugin/badnamed.plugin.php' );

	try{
	    $plugins = new plugins();
	    $this->fail('An exception was expected');
	} catch ( waterwheelexception $e ) {
	    if ( $e->getMessage() == 'Plugin classname is not included within the plugin file name.' ){
		$this->pass('The correct exception was thrown');
	    } else {
		$this->fail('An incorrect exception was thrown: ' .  $e->getMessage());
	    }
	}

	//rename the file back again so it won't cause errors
	rename( APPLICATION_PATH . '/plugins/testplugin/badnamed.plugin.php', APPLICATION_PATH . '/plugins/testplugin/badnamed.php' );

    }
    
    /**
     * Tests the return value of get_loaded
     */
    function testGetLoaded(){
	
	$plugins = new plugins();
	
	$loaded = $plugins->get_loaded();

	//get loaded should contain only one item, the operational plugin
	$this->assertTrue(count($loaded) == 1, 'Only one plugin is loaded');

	//test that we get an array back
	$this->assertTrue( is_array($loaded) , 'Test get loaded is an array' );
	
	//test that the items in the array are classes that extend plugin
	$this->assertTrue( is_object(current($loaded)) , 'Test array items returned by get loaded are objects' );
	$this->assertTrue( is_a(current($loaded),plugin) , 'Test array items returned by get loaded are plugin objects' );
	
    }

    /**
     * Test the check to see if a plugin is loaded
     */
    function testPluginIsLoaded(){

	//operational should be loaded and therefore return true
	$this->assertTrue( plugins::is_loaded('operational') , 'checking if operational plugin is loaded returns true' );

	//badlynamedplugin should not and therefore return false
	$this->assertFalse( plugins::is_loaded('badlynamedplugin') , 'checking if badlynamedplugin plugin is loaded returns false' );

    }

    function testActionWithoutValue(){

	//the operational plugin will throw an exception if the
	//correct function runs.

	try{
	    plugins::action('test_action_without_value');
	    $test->fail('An exception was expected');
	} catch( waterwheelexception $e ){
	    if ( $e->getMessage() == 'test_action' ){
		$this->pass('The correct exception was thrown');
	    } else {
		$this->fail('A different exception was expected: ' . $e->getMessage());
	    }
	}



    }

    function testActionWithValue(){

	//the operational plugin will throw an exception if the
	//correct function runs. The exceptionmessage will be the value passed.

	try{
	    plugins::action('test_action_with_value' , 'test_value');
	    $test->fail('An exception was expected');
	} catch( waterwheelexception $e ){
	    if ( $e->getMessage() == 'test_value' ){
		$this->pass('The correct exception was thrown');
	    } else {
		$this->fail('A different exception was expected: ' . $e->getMessage());
	    }
	}

    }

    function testFilter(){
	//the plugin is read to hook into the test filter
	//the filter will add the two passed values together
	$this->assertTrue( plugins::filter('test_filter', array(2,2)) == 4, 'Test filter operates and returns the expected value.');
    }

    function testFilterWithNoReturnValue(){

	try{
	    plugins::filter('test_filter_with_no_return_value' , 'test_value');
	    $test->fail('An exception was expected');
	} catch( waterwheelexception $e ){
	    if ( $e->getMessage() == 'Plugin filter did not return a value.' ){
		$this->pass('The correct exception was thrown');
	    } else {
		$this->fail('A different exception was expected: ' . $e->getMessage());
	    }
	}


    }

    function testUnloadPlugin(){

	//unload the operational plugin
	plugins::unload('operational');

	//there should now be no plugins loaded
	$loaded = plugins::get_loaded();

	$this->assertTrue(count($loaded) == 0);
	$this->assertFalse(plugins::is_loaded('operational'));

    }

}

?>